#include "ffstartevent.h"

FFStartEvent::FFStartEvent(FFPlayerContext* playerCtx, const std::string& url_)
    : FFEvent(playerCtx), url(url_)
{
    demuxerThread = playerCtx->demuxerThread;
    vDecoderThread = playerCtx->vDecoderThread;
    aDecoderThread = playerCtx->aDecoderThread;
    aRender = playerCtx->aRender;
    vRender = playerCtx->vRender;
    demuxer = playerCtx->demuxer;
    aDecoder = playerCtx->aDecoder;
    vDecoder = playerCtx->vDecoder;
    aPktQueue = playerCtx->aPktQueue;
    vPktQueue = playerCtx->vPktQueue;
    aFrmQueue = playerCtx->aFrmQueue;
    vFrmQueue = playerCtx->vFrmQueue;
    playerWindow = playerCtx->playerWindow;
}

void FFStartEvent::work()
{
    stopAll();
    initAll();
    startAll();
}

void FFStartEvent::stopAll()
{
    demuxerThread->stop();
    demuxerThread->wakeAllThread();
    demuxerThread->wait();
    demuxerThread->close();

    std::cerr<<"demuxerThread stop!"<<std::endl;

    aRender->wakeAllThread();
    vRender->wakeAllThread();

    aDecoderThread->stop();
    aDecoderThread->wait();
    aDecoderThread->close();

    std::cerr<<"aDecoderThread stop!"<<std::endl;
    vDecoderThread->stop();
    vDecoderThread->wait();
    vDecoderThread->close();
    std::cerr<<"vDecoderThread stop!"<<std::endl;

    aPktQueue->close();
    vPktQueue->close();
    std::cerr<<"aPktQueue stop!"<<std::endl;

    aFrmQueue->close();
    vFrmQueue->close();
    std::cerr<<"aFrmQueue stop!"<<std::endl;

    aRender->stop();
    aRender->wait();
    aRender->close();
    std::cerr<<"aRender stop!"<<std::endl;

    vRender->stop();
    vRender->wait();
    vRender->close();
    std::cerr<<"vRender stop!"<<std::endl;
}

void FFStartEvent::initAll()
{
    demuxer->init(url, aPktQueue, vPktQueue);
    demuxerThread->init(demuxer);

    aDecoder->init(demuxer->getAStream(), aFrmQueue);
    aDecoderThread->init(aDecoder, aPktQueue);

    vDecoder->init(demuxer->getVStream(), vFrmQueue);
    vDecoderThread->init(vDecoder, vPktQueue);

    aRender->init(aFrmQueue, aDecoder, playerWindow);
    vRender->init(vDecoder, vFrmQueue, playerWindow);
}

void FFStartEvent::startAll()
{
    aPktQueue->start();
    vPktQueue->start();

    aFrmQueue->start();
    vFrmQueue->start();

    demuxerThread->start();

    vDecoderThread->start();
    aDecoderThread->start();

    vRender->start();
    vRender->wakeAllThread();

    aRender->start();
    aRender->wakeAllThread();
}
